home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Compilers⁄Interps
/
kevoSource
/
kevo.img
< prev
next >
Wrap
Text File
|
1993-05-13
|
36KB
|
990 lines
(( Kevo Interactive Compiler Kernel ))
(( Copyright Antero Taivalsaari 1991-1992 ))
(( Some parts copyright Antero Taivalsaari 1986-1988 ))
(( kevo.img: basic high-level definitions image file ))
(( This file is represented in so-called immediate-free ))
(( form, which can be loaded into the Kevo kernel as such ))
(( without any compilation. Actual high-level definitions ))
(( of these operations would look more sophisticated. ))
(( -------------------------------------------------------- ))
(( Note that this file may still contain some non-object-oriented ))
(( stuff which is not intended to be used any more. ))
(( System root context (context = name space, dictionary) ))
:: SystemRoot 2 (=context) 0 ;; 0
(( Basic user definition context ))
:: Root 2 (=context) 0 ;; 0
(( Task-specific areas which are not necessarily needed for all tasks. ))
(( For safety, each execution stack has a four item underflow area ))
:: (returnStack) 134 (( return stack: initially room for 128 items ))
(=context) DUMMY
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;; 08
:: (dataStack) 70 (( data stack: initially room for 64 items ))
(=context) DUMMY
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;; 08
:: (contextStack) 38 (( context stack: initially room for 32 items ))
(=context) DUMMY
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;; 08
:: (trampoline) 4 0 0 0 0 ;; 08
:: (textBuffer) 32 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 ;; 08
:: (infileStack) 8 0 0 0 0 0 0 0 0 ;; 08
:: (outfileStack) 4 0 0 0 0 ;; 08
(( Task-specific variable area (each task has one of these areas). ))
(( Do not change the order of the first n fields (above the line), ))
(( because C primitives refer to them directly. ))
(( If you nevertheless change the order, the corresponding changes ))
(( must be done in file 'tasks.h', and the Kevo system has to be ))
(( recompiled. ))
:: (user) 42 (( this must be increased when new task-specific vars are added ))
(=context) DUMMY (( use the internal dummy (empty) context ))
(( so as to make area viewable by browser ))
(( nextInRobin )) (user) (( must point to itself ))
(( nextTask )) 0
(( rpStore )) 0
(( fp )) 0 (( frame pointer ))
(( priority )) 50 (( the current priority ))
(( returnStack )) (returnStack)
(( dataStack )) (dataStack)
(( contextStack )) (contextStack)
(( trampoline )) (trampoline)
(( textBuffer )) (textBuffer)
(( textHead )) 0 (( text buffer offsets ))
(( textTail )) 0
(( eof )) 0 (( end of file flag ))
(( infiles )) (infileStack)
(( outfiles )) (outfileStack)
(( infile' )) 0
(( outfile' )) 0
(( infile )) 0
(( outfile )) 0
(( errfile )) 0
(( window )) 0
(( path )) Root
(( assigning )) 0
(( error )) oopError
(( ----------------------------------------------------------------))
(( user' )) 38 (( This must be increased if you add ))
(( compilation )) 0 (( new task variables ))
(( target )) 0
(( latest )) 0
(( frameSize )) 0
(( whoToModify )) 0
(( controls )) 0
(( warnings )) 0
(( tram' )) 0
(( comp' )) 0
(( text' )) 0
(( input )) 0
(( extra space )) 0 0 0 0 ;; 08
(( eof-field is referred to directly in operation 'setEof' so if you add new ))
(( user variables, remember to change that too ))
(( Offsets to task-specific system variables ))
(( First four may not be referred to by the user ))
(( :: nextInRobin 2 (=taskConst) 2 ;; 08 ))
(( :: nextTask 2 (=taskConst) 3 ;; 08 ))
(( :: rpStore 2 (=taskConst) 4 ;; 08 ))
(( :: fp 2 (=taskConst) 5 ;; 08 )) (( temp variable frame pointer ))
:: priority 2 (=taskVar) 6 ;; 00 (( the priority of the task ))
:: returnStack 2 (=taskConst) 7 ;; 08
:: dataStack 2 (=taskConst) 8 ;; 08
:: contextStack 2 (=taskConst) 9 ;; 08
:: trampoline 2 (=taskConst) 10 ;; 08 (( interactive execution area ))
:: textBuffer 2 (=taskConst) 11 ;; 08
:: textHead 2 (=taskConst) 12 ;; 08
:: textTail 2 (=taskConst) 13 ;; 08
:: eof 2 (=taskConst) 14 ;; 0 (( xxx referred to directly in 'raiseEof' ))
:: infiles 2 (=taskConst) 15 ;; 08
:: outfiles 2 (=taskConst) 16 ;; 08
:: infile' 2 (=taskConst) 17 ;; 08
:: outfile' 2 (=taskConst) 18 ;; 08
:: infile 2 (=taskConst) 19 ;; 08
:: outfile 2 (=taskConst) 20 ;; 08
:: errfile 2 (=taskConst) 21 ;; 08
:: window 2 (=taskVar) 22 ;; 08 (( the output window of the task ))
:: path 2 (=taskVar) 23 ;; 08 (( not in use in the current version ))
:: assigning 2 (=taskVar) 24 ;; 08 (( to-variable assignment counter ))
:: error 2 (=taskVector) 25 ;; 0 (( vectored error routine ))
:: user' 2 (=taskVar) 26 ;; 08 (( the number of task variables ))
:: compilation 2 (=taskVar) 27 ;; 08 (( current definition ))
:: target 2 (=taskVar) 28 ;; 08 (( the name of -"- ))
:: latest 2 (=taskVar) 29 ;; 08 (( latest defined name ))
:: frameSize 2 (=taskVar) 30 ;; 08 (( number of temporary variables ))
:: whoToModify 2 (=taskVar) 31 ;; 0
:: controls 2 (=taskVar) 32 ;; 08
:: warnings 2 (=taskVar) 33 ;; 0
:: tram' 2 (=taskVar) 34 ;; 08 (( execution area offset ))
:: comp' 2 (=taskVar) 35 ;; 08 (( compilation area offset ))
:: text' 2 (=taskVar) 36 ;; 08
:: input 2 (=taskVar) 37 ;; 08
(( Default stack sizes. yyy Note: the offset 6 below is ))
(( non-portable and depends on DATAOFFSET + UNDERFLOWRESERVE ))
:: sp# 7 dataStack object'size @ (lit) 6 - exit ;; 0 (( data stack size ))
:: rp# 7 returnStack object'size @ (lit) 6 - exit ;; 0 (( return stack size ))
:: cp# 7 contextStack object'size @ (lit) 6 - exit ;; 0 (( context stack size ))
(( Basic input/output extensions ))
(( To allow multitasking, Kevo's I/O primitives operate on a character at ))
(( a time basis. In mainframe environment, this obviously consumes more ))
(( processor time. However, within the Kevo system processor time ))
(( utilization is pretty efficient. Furthermore, this solution is fully ))
(( portable, which has been one of the main objectives in designing Kevo. ))
(( Macintosh Kevo uses a slightly different (event-driven) I/O scheme, ))
(( so many of these definitions have been commented out. ))
:: "bs" 2 (=sharedConst) 8 ;; 0
:: "tab" 2 (=sharedConst) 9 ;; 0
:: "lf" 2 (=sharedConst) 10 ;; 0
:: "cr" 2 (=sharedConst) 13 ;; 0
:: "bl" 2 (=sharedConst) 32 ;; 0
:: "del" 2 (=sharedConst) 127 ;; 0
:: tab 3 "tab" emit exit ;; 0
(( :: cr 3 "cr" emit exit ;; 0 ))
:: space 3 "bl" emit exit ;; 0
(( :: spaces 7 one (do) 4 space (loop) -2 exit ;; 0 ))
(( :: type 12 dup b@ (if) 7 dup b@ emit 1+ (branch) -9 drop exit ;; 0 ))
:: ltype 9 >r count r> swap - swap type spaces exit ;; 0
:: rtype 8 >r count r> swap - spaces type exit ;; 0
:: key 9 key? eof (if) 2 exit ?dup (if) -7 exit ;; 0
:: stdInput? 3 infile' 0= exit ;; 08
:: (delText) 6 dup 0> (if) 2 1- exit ;; 08
(( :: (delText) 12 dup 0> (if) 8 1- "bs" emit "bl" emit "bs" emit exit ;; 08 ))
:: (addText) 8 over (lit) 5 pick + b! 1+ exit ;; 08
:: (cutText) 4 nip + boff exit ;; 08
:: expect 39 zero
2dup <=
(if) 3 (cutText) exit
key dup "cr" <> over "lf" <> and eof not and
(if) 17
dup "bs" = over "del" = or
(if) 5 drop (delText) (branch) 2
(( stdInput? (if) 3 dup emit ))
(addText)
(branch) -34
(( "cr" = stdInput? and (if) 2 cr )) drop
(cutText) exit ;; 0
(( Error messages ))
:: msg$dEmpty 5 errorTo ^^ -- Data stack empty^^ type exit ;; 08
:: msg$dFull 5 errorTo ^^ -- Data stack full^^ type exit ;; 08
:: msg$rEmpty 5 errorTo ^^ -- Return stack empty^^ type exit ;; 08
:: msg$rFull 5 errorTo ^^ -- Return stack full^^ type exit ;; 08
:: msg$cEmpty 5 errorTo ^^ -- Context stack empty^^ type exit ;; 08
:: msg$cFull 5 errorTo ^^ -- Context stack full^^ type exit ;; 08
:: msg$control 5 errorTo ^^ -- Illegal control structure^^ type exit ;; 08
:: msg$what 5 errorTo ^^ -- ???^^ type exit ;; 08
:: msg$"what 9 errorTo ^^ -- ??? --> ("^^ type type ^^ ")^^ type exit ;; 08
:: msg$execOnly 5 errorTo ^^ -- Outside of definitions only^^ type exit ;; 08
:: msg$compOnly 5 errorTo ^^ -- Within definitions only^^ type exit ;; 08
:: msg$notObj 5 errorTo ^^ -- Given parameter is not an object^^ type exit ;; 08
:: msg$noDot 5 errorTo ^^ -- Message syntax error^^ type exit ;; 08
:: msg$notImpl 5 errorTo ^^ -- Binding error (property not implemented)^^ type exit ;; 08
:: msg$notAvail 5 errorTo ^^ -- Binding error (property not available)^^ type exit ;; 08
:: msg$unimpl 5 errorTo ^^ -- Unimplemented language feature^^ type exit ;; 08
:: ensureStruct 6 <> (if) 3 msg$control error exit ;; 08
:: notImplemented 3 msg$notImpl error exit ;; 0
:: notAvailable 3 msg$notAvail error exit ;; 0
:: inRange 9 between not (if) 5 ^^ -- Out of range^^ type error exit ;; 0
(( Execution state manipulation ))
(( Kevo compiler has two states: execution and compilation. In the compilation ))
(( state the given definitions will be stored permanently to a dictionary ))
(( (name space). In the execution mode, the compiled code will be executed ))
(( and disposed of right after the compilation (in trampoline) ))
:: >compile 5 compilation @ target ! exit ;; 0
:: >execute 4 trampoline target ! exit ;; 0
:: executing 5 target @ trampoline = exit ;; 0
:: compiling 5 target @ trampoline <> exit ;; 0
:: mustCompile 6 executing (if) 3 msg$compOnly error exit ;; 0
:: mustExecute 6 compiling (if) 3 msg$execOnly error exit ;; 0
(( Pseudovariables ))
(( xxx0 implies the _beginning_ of something ))
(( xxx' implies the current _pointer_ to something ))
(( xxx# implies the current _size_ of something ))
:: user0 4 up @ object>store exit ;; 08
:: user# 5 up @ object'size @ exit ;; 08
:: text0 3 textBuffer object>store exit ;; 08
:: text# 5 textBuffer object'size @ cell* exit ;; 08
:: infile0 3 infiles object>store exit ;; 08
:: infile# 4 infiles object'size @ exit ;; 08
:: outfile0 3 outfiles object>store exit ;; 08
:: outfile# 4 outfiles object'size @ exit ;; 08
:: tram0 3 trampoline object>store exit ;; 08
:: tram# 4 trampoline object'size @ exit ;; 08
:: comp0 4 compilation @ object>store exit ;; 08
:: comp# 5 compilation @ object'size @ exit ;; 08
:: here0 4 target @ object>store exit ;; 08
:: here' 8 compiling (if) 4 comp' (branch) 2 tram' exit ;; 08
:: here# 5 target @ object'size @ exit ;; 08
:: here 3 here' @ exit ;; 0
(( Compilation primitives ))
(( These differ considerably from the seemingly similar definitions in Forth ))
(( Our language supports dynamic memory management, so the allotted memory must ))
(( be able to expand and shrink automatically ))
:: allot 17 align dup here + cell/ here# - 1+ zero max cell*
target @ <expand> here' +! exit ;; 0
:: , 7 here0 here + ! cell allot exit ;; 0
:: compile, 7 here0 here + ! cell allot exit ;; 0 (( defined for portability ))
:: override, 6 here0 here cell- + ! exit ;; 0
:: literal, 5 (lit) (lit) compile, , exit ;; 0
:: "literal, 6 (lit) ("lit) compile, <buildString> , exit ;; 0
:: (compile) 7 r> dup @ compile, cell+ >r exit ;; 08
(( Execution area (trampoline) memory management ))
:: tramAllot 17 align dup tram' @ + cell/ tram# - 1+ zero max cell*
trampoline <expand> tram' +! exit ;; 08
:: tram, 8 tram0 tram' @ + ! cell tramAllot exit ;; 08
(( Task data area management ))
(( These operations are not really intended for high-level use ))
(( note that userAllot parameters are cells rather than bytes ))
:: userAllot 16 dup user' @ + user# - 1+ zero max cell*
up @ <expand> user' +! exit ;; 0
:: user, 9 user0 user' @ cell* + ! one userAllot exit ;; 0
(( Code execution primitives ))
(( These are something which you cannot find in normal Forth systems. ))
(( They allow control structures to operate interactively, which is ))
(( a major advantage over conventional implementations. ))
(( Note that after a piece of interactively written and compile code has ))
(( been executed it will be automatically deallocated ))
:: cycle 8 tram# <buildStore> trampoline object'store ! tram' off exit ;; 08
:: go 16 tram' @ (if) 12
(lit) (lit) tram,
tram0 tram, (( set the code to dispose of itself ))
(lit) freeExit tram,
tram0 cycle <executeStore>
exit ;; 08
(( Unix-like pipe: the code left of | will be compiled and executed ))
(( as if it were a separate line ))
:: (|) 8 controls @ (if) 3 msg$control error go exit ;; 08
:: | 9 compiling (if) 5 (compile) (|) (branch) 2 (|) exit ;; 80
(( Message sending primitives ))
:: top 1 exit ;; 80
:: send 3 >send self>drop exit ;; 08
:: resend 7 mustCompile latest @ literal, (compile) >resend exit ;; 80
(( Command input stream management ))
(( Again some of these have been commented, because the Mac implementation ))
(( uses a slightly different I/O strategy ))
:: prepareText 11 text0 count + 1+ boff text0 text' ! input off exit ;; 08
(( :: query 6 text0 text# 2- expect prepareText exit ;; 0 ))
:: query 8 textAvailable (if) -2 text' ! input off exit ;; 0
:: (parse) 27 text' @ b@
(if) 18 text' @ skipWhite dup dup input ! scanWhite dup
zero swap b! 1+ text' ! (branch) 5
input off text' @
exit ;; 08
:: PARSE 10 compiling (if) 5 (compile) (parse) (branch) 3
(parse) "literal, exit ;; 80
:: (word) 28 text' @ b@
(if) 18 text' @ dup dup input ! rot scan dup zero swap b!
1+ text' ! (branch) 6
drop input off text' @ exit ;; 08
:: WORD 11 compiling (if) 5 (compile) (word) (branch) 4
(|) (word) "literal, exit ;; 80
:: ( 5 (lit) 41 (word) drop exit ;; 80
:: \ 4 zero (word) drop exit ;; 80
:: " 5 (lit) 34 (word) "literal, exit ;; 80
:: ." 4 " (compile) type exit ;; 80
:: ^ 5 (lit) 94 (word) "literal, exit ;; 80
:: .^ 4 ^ (compile) type exit ;; 80
:: checkStacks 40
depth 0< (if) 3 msg$dEmpty error
depth sp# > (if) 3 msg$dFull error
rdepth 0< (if) 3 msg$rEmpty error
rdepth rp# > (if) 3 msg$rFull error
cdepth 0< (if) 3 msg$cEmpty error
cdepth cp# > (if) 3 msg$cFull error
exit ;; 0
:: resetContext 12 cdepth 0> (if) 5 self resetCp >self exit
resetCp Root >self exit ;; 0
(( Threaded code compiler ))
:: encode 2 (=sharedVector) ooEncode ;; 08
:: (encode) 24 dup search
(if) 12 nip dup immediate?
(if) 4 name>object execute exit
name>object compile, exit
number (if) 4 literal, (branch) 3
msg$what error
exit ;; 08
(( Dot expression (message) parser ))
:: noDotsAtAll 6 (lit) 46 scan b@ 0= exit ;; 08
:: dotInBeginning 5 b@ (lit) 46 = exit ;; 08
:: dotInEnd 8 count + 1- b@ (lit) 46 = exit ;; 08
:: dotExpression 24 dup noDotsAtAll (if) 3 false exit
dup dotInBeginning (if) 3 false exit
dup dotInEnd (if) 3 false exit
dup (lit) 46 enclose true exit ;; 08
:: message, 4 "literal, (compile) send exit ;; 08
:: skipDot 4 count + 1+ exit ;; 08
:: innerMessages 9 skipDot dotExpression
(if) 5 dup message,
(branch) -7 exit ;; 08
:: lastMessage 12 dup noDotsAtAll
(if) 5 assignment? message,
(branch) 4 drop msg$noDot error exit ;; 08
:: encodeMessages 10 dup (encode) executing (if) 3 (compile) mustBeObject
innerMessages lastMessage exit ;; 08
:: ooEncode 9 dotExpression
(if) 4 encodeMessages (branch) 3
assignment? (encode) exit ;; 0
(( Command interface ))
:: interpret 17 (parse) dup b@ (if) 4 encode (branch) -7
drop controls @ 0= (if) 2 go checkStacks exit ;; 0
:: .ok 5 ^^ ok^^ type cr exit ;; 0
:: prompt 11 controls @ 0= stdInput? and
(if) 4 popOutfile .s .ok
exit ;; 0
(( This is the big kabloona: the Kevo kernel command shell ))
:: shell 10 controls off resetContext cycle >execute
prompt query interpret (branch) -4 ;; 0
(( Error handling ))
:: resetFiles 3 resetInfiles resetOutfiles exit ;; 0
:: abort 4 resetSp resetFiles reboot shell ;; 0
(( the main error handler; resets stacks, files, textbuffers etc. ))
(( and prints the end part of the error message ))
:: (error) 36 resetSp input @ ?dup
(if) 21 ^^ --> ("^^ type type ^^ ")^^ type
compiling (if) 9
^^ in: ^^ type latest @ name'name @ type (branch) 4
^^ --> (runtime)^^ type
cr resetFiles eraseText input off
reboot shell ;; 08
(( the object-oriented error handler ))
(( prints context stack trace when its depth >1 ))
:: oopError 19 cdepth one >
(if) 12 ^^ traceBack^^ self searchThis
(if) 3 name>object execute
self>drop
(branch) -15
resetContext (error) exit ;; 0
(( don't remove this; needed internally by the browser ))
:: brError 5 bell bell |> oopError exit ;; 08
(( Name space management ))
(( return the name field address given a string ))
:: find 9 dup search
(if) 3 nip exit
msg$"what error
exit ;; 0
(( return the execution address given a string ))
:: tick 3 find name>object exit ;; 0
(( check if a word can be found in the name space ))
:: DEFINED 12 (parse) search
(if) 6 drop (compile) true (branch) 3
(compile) false
exit ;; 80
(( high-level versions of 'find' and 'tick' ))
:: FIND 4 (parse) find literal, exit ;; 80
:: ' 4 (parse) tick literal, exit ;; 80
(( The following ops have been implemented for backward compatibility. ))
(( The same effect can be achieved more reliably with module operations. ))
:: forget 3 find <deleteName> exit ;; 0
(( can create garbage which should be collected ))
:: FORGET 5 (parse) "literal, (compile) forget exit ;; 80
:: forgetRest 14 find name'succ @ ?dup
(if) 8
dup name'succ @ swap <deleteName>
(branch) -9
exit ;; 0
:: empty 4 ^^ boot^^ forgetRest exit ;; 0
(( Compilation auxiliaries ))
:: ASCII 4 (parse) b@ literal, exit ;; 80
:: "interpret 7 count 1+ text0 move prepareText interpret exit ;; 0
:: COMPILE 6 (parse) tick (compile) (compile) , exit ;; 80
:: NOW 4 (parse) tick execute exit ;; 80
:: LATER 4 (parse) tick compile, exit ;; 80
:: (=>) 4 object>store cell+ ! exit ;; 08
:: => 4 ' (compile) (=>) exit ;; 80
:: (tick&) 3 object>store cell+ exit ;; 08
:: '& 4 ' (compile) (tick&) exit ;; 80
(( access another task's data area ))
:: his 5 cell* swap object>store + exit ;; 08
:: HIS 9 (parse) tick object>store cell+ @ literal,
(compile) his exit ;; 80
(( access our own task data area ))
:: my 4 cell* user0 + exit ;; 08
:: MY 9 (parse) tick object>store cell+ @ literal,
(compile) my exit ;; 80
:: -> 3 assigning on exit ;; 80
:: assignment? 9 assigning @ (if) 5 (compile) (->) assigning off exit ;; 08
(( System extension operations ))
:: immediate 6 "immediate" latest @ name'flags toggle exit ;; 0
:: hidden 6 "hidden" latest @ name'flags toggle exit ;; 0
:: smudge 6 "smudge" latest @ name'flags toggle exit ;; 0
:: unsmudge 6 "smudge" latest @ name'flags untoggle exit ;; 0
:: default# 2 (=sharedConst) 2 ;; 08 (( default size of definitions ))
(( warn the user about possible overriding of names ))
:: warn 25 warnings @
(if) 20
^^ Defining ^^ type dup type
search
(if) 7 drop ^^ (previous definition overridden).^^ type cr exit
(lit) 46 emit cr exit
drop exit ;; 08
(( warn the user about redefinitions ))
:: rewarn 15 warnings @
(if) 10
^^ Redefining ^^ type type
(lit) 46 emit cr exit
drop exit ;; 08
:: (create) 12 default# <buildObject> dup compilation !
latest @ name'object !
comp' off exit ;; 0
(( create/override an entry in a name space ))
:: create 8 dup warn
self <buildName> latest !
(create) exit ;; 0
:: (replace) 23 dup latest ! dup name'flags off
name>object compilation !
(( <freeStore> can crash the system if the code is run by other tasks ))
(( compilation @ <freeStore> ))
default# <buildStore> compilation @ object'store !
default# compilation @ object'size ! comp' off exit ;; 08
(( given a string, redefine the corresponding property ))
(( this operation changes the behavior of all the objects ))
(( who refer to the property ))
:: replace 6 dup find swap rewarn (replace) exit ;; 0
:: (recreate) 12 dup latest ! dup name'flags off
name>object (create) latest @ <recompile> exit ;; 08
(( given a string, redefine the corresponding property ))
(( this operation preserves the behavior of other objects ))
(( all the references to the property in this object (family) ))
(( are rebound using primitive '<recompile>' ))
:: recreate 6 dup find swap rewarn (recreate) exit ;; 0
:: (:) 6 >compile smudge controls ++ ":" exit ;; 08
(( don't remove this; needed internally by browser's method redefiner ))
:: bredef 31 mustExecute
dup "thisOnly" = (if) 10 drop self <derive> dup self <rePair> (recreate) (:) exit
dup "wholeFamily" = (if) 5 drop (recreate) (:) exit
"derivatives" = (if) 3 (replace) (:) exit ;; 08
(( access words to the storage part of the latest definition ))
:: does, 3 comp0 ! exit ;; 0
:: with, 4 comp0 cell+ ! exit ;; 0
(( this word is implemented for Forth-compatibility ))
:: CREATE 13 compiling (if) 6 (compile) (parse) immediate (branch) 3
(parse) "literal,
(compile) create exit ;; 80
:: : 5 mustExecute (parse) create (:) exit ;; 80
:: ; 11 mustCompile controls -- ":" ensureStruct
unsmudge (lit) exit compile,
(( compilation @ <optimize> )) >execute exit ;; 80
:: recurse 5 mustCompile compilation @ compile, exit ;; 80
:: myself 8 (compile) (branch) zero here - cell/ , exit ;; 80
(( Multitasker extensions ))
:: stop 7 resetFiles up @ suspend yield reboot shell ;; 0
(( :: (bgError) 9 resetSp ^^ --> (background task)^^ type cr
resetFiles stop reboot shell ;; 08 ))
(( the following six operations are preserved for backwards ))
(( compatibility with earlier versions of Kevo ))
(( background task creation (no window) ))
:: bgtask 7 create (lit) (=sharedConst) does, <buildBGTask> with, exit ;; 0
:: BGTASK 5 (parse) "literal, (compile) bgtask exit ;; 80
(( graphics task creation (no Mac TextEdit services ) ))
:: grtask 7 create (lit) (=sharedConst) does, <buildGRTask> with, exit ;; 0
:: GRTASK 5 (parse) "literal, (compile) grtask exit ;; 80
(( full task creation (window with TextEdit) ))
:: task 7 create (lit) (=sharedConst) does, <buildTETask> with, exit ;; 0
:: TASK 5 (parse) "literal, (compile) task exit ;; 80
(( Unix-like background tasks ))
(( background tasks kill themselves automatically ))
(( files are also closed ))
:: killExit 6 <free> resetFiles up @ <killTask> exit ;; 08
(( pipe to background (see '(|)' above) ))
:: (BG|) 17 controls @
(if) 3 msg$control error
(lit) (lit) tram,
tram0 tram,
(lit) killExit tram,
tram0 cycle exit ;; 08
(( The code for background tasks ))
(( The actual code is given as a parameter in the data stack ))
:: (runBG) 2 <executeStore> exit ;; 08
(( Define an operation to execute on background ))
:: BG 13 mustExecute (BG|) <buildBGTask> >r
(lit) (runBG) r@ does
r@ >taskData
r> activate exit ;; 80
(( Debugger extensions ))
(( Note that debugging can be used only on non-primitive operations ))
(( set a breakpoint at a certain operation ))
:: debug 23 dup object'size @ 1- cell* swap object>store + dup @
(lit) exit = (if) 7 (lit) debugExit swap ! (branch) 2 drop exit ;; 0
(( remove a breakpoint from an operation ))
:: unbug 23 dup object'size @ 1- cell* swap object>store + dup @
(lit) debugExit = (if) 7 (lit) exit swap ! (branch) 2 drop
exit ;; 0
(( shorthand for resume ))
:: r 2 resume exit ;; 0
(( Variable, constant, vector and context declaration ))
:: sharedVar 5 create (lit) (=sharedVar) does, exit ;; 0
:: taskVar 10 create (lit) (=taskVar) does, user' @ with, zero user, exit ;; 0
:: sharedConst 6 create (lit) (=sharedConst) does, with, exit ;; 0
:: taskConst 9 create (lit) (=taskConst) does, user' @ with, user, exit ;; 0
:: sharedVector 6 create (lit) (=sharedVector) does, with, exit ;; 0
:: taskVector 9 create (lit) (=taskVector) does, user' @ with, user, exit ;; 0
(( The following three definitions are added for Forth-compatibility ))
:: VARIABLE 5 (parse) "literal, (compile) sharedVar exit ;; 80
:: CONSTANT 5 (parse) "literal, (compile) sharedConst exit ;; 80
:: DEFER 5 (parse) "literal, (compile) sharedVector exit ;; 80
(( Semaphore operations for monitor implementation ))
(( These operations can be associated with any REF or VAR ))
:: (wait) 22 ({) (->) <temp> temp: 1 execute 0= (if) 4 yield (branch) -8
temp: 1 execute 1- temp: 1 (->) execute (}) exit ;; 08
:: (signal) 7 dup execute 1+ swap (->) execute exit ;; 08
:: WAIT 4 ' (compile) (wait) exit ;; 80
:: SIGNAL 4 ' (compile) (signal) exit ;; 80
(( Context creation and maneuvering ))
:: mkdir 7 create (lit) (=REF) does, <mkdir> with, exit ;; 0
:: MKDIR 5 (parse) "literal, (compile) mkdir exit ;; 80
:: context 9 create (lit) (=context) does, compilation @ <buildContext> with, exit ;; 0
:: CONTEXT 5 (parse) "literal, (compile) context exit ;; 80
:: mustBeObject 9 dup hasContext not (if) 4 drop msg$notObj error exit ;; 0
:: CD 4 mustBeObject >self resetContext exit ;; 0
:: cd 6 CD ^^ Context is now: ^^ type .cs exit ;; 0
:: pwd 2 .cs exit ;; 0
:: home 3 Root CD exit ;; 0
(( Object definition high-level words ))
(( ---------------------------------- ))
(( property addition module operations ))
(( Note: ADDS/ADDS* has a small shortcut: ))
(( 'whoToModify' information should be stored ))
(( in a stack so as to allow unlimited nesting ))
(( of ADDS...ENDADDS; structures xxx ))
:: (ADDS) 7 dup <derive> >self "thisOnly" whoToModify ! exit ;; 08
:: ADDS 3 (compile) (ADDS) exit ;; 80
:: (ADDS*) 5 >self "wholeFamily" whoToModify ! exit ;; 08
:: ADDS* 3 (compile) (ADDS*) exit ;; 80
:: ADDS** 3 msg$unimpl error exit ;; 80
:: (REF) 5 create (lit) (=REF) does, exit ;; 08
:: REF 5 (parse) "literal, (compile) (REF) exit ;; 80
:: (VAR) 12 create (lit) (=VAR) does,
self object'size @ with,
one self <expandFamily> exit ;; 08
:: VAR 5 (parse) "literal, (compile) (VAR) exit ;; 80
:: SHAREDVAR 2 REF exit ;; 80
:: CONST 5 (parse) "literal, (compile) sharedConst exit ;; 80
:: METHOD 2 : exit ;; 80
:: (ENDADDS) 15 cdepth one >
(if) 8
whoToModify @ self <reorganize>
self>drop (branch) 3
msg$control error
exit ;; 08
:: ENDADDS; 3 (compile) (ENDADDS) exit ;; 80
(( redefinition module operations ))
(( Note: these operations do not preserve the current context ))
:: REDEFINE 8 (|) dup <derive> CD (parse) recreate (:) exit ;; 80
:: REDEFINE* 6 (|) CD (parse) recreate (:) exit ;; 80
:: REDEFINE** 6 (|) CD (parse) replace (:) exit ;; 80
(( renaming module operations ))
:: rename 13 rot dup <derive> >self swap find swap <renameName>
"thisOnly" self <reorganize> self>drop exit ;; 0
:: RENAME 5 (parse) "literal, (compile) rename exit ;; 80
:: rename* 8 rot >self <renameName> "wholeFamily" self <reorganize> self>drop exit ;; 0
:: RENAME* 6 FIND (parse) "literal, (compile) rename* exit ;; 80
:: RENAME** 3 msg$unimpl error exit ;; 80
(( removal module operations ))
:: remove 11 swap dup <derive> >self find <deleteName>
"thisOnly" self <reorganize> self>drop exit ;; 0
:: REMOVE 5 (parse) "literal, (compile) remove exit ;; 80
:: remove* 8 swap >self <deleteName> "wholeFamily" self <reorganize> self>drop exit ;; 0
:: REMOVE* 4 FIND (compile) remove* exit ;; 80
:: REMOVE** 3 msg$unimpl error exit ;; 80
(( encapsulation module operations ))
:: hide 14 swap dup <derive> >self "hidden" swap find name'flags toggle
"thisOnly" self <reorganize> self>drop exit ;; 0
:: HIDE 5 (parse) "literal, (compile) hide exit ;; 80
:: hide* 8 swap >self "hidden" swap name'flags toggle self>drop exit ;; 0
:: HIDE* 4 FIND (compile) hide* exit ;; 80
:: HIDE** 3 msg$unimpl error exit ;; 80
:: show 14 swap dup <derive> >self "hidden" swap find name'flags untoggle
"thisOnly" self <reorganize> self>drop exit ;; 0
:: SHOW 5 (parse) "literal, (compile) show exit ;; 80
:: show* 8 swap >self "hidden" swap name'flags untoggle self>drop exit ;; 0
:: SHOW* 4 FIND (compile) show* exit ;; 80
:: SHOW** 3 msg$unimpl error exit ;; 80
(( ---------------------------------- ))
(( Control structure branch offset calculation ))
:: mark> 4 here zero , exit ;; 08
:: resolve> 9 here over - cell/ swap here0 + ! exit ;; 08
:: mark< 2 here exit ;; 08
:: resolve< 5 here - cell/ , exit ;; 08
(( Arbitrary constants for control structure syntax checking ))
:: "if" 2 (=sharedConst) 11111 ;; 08
:: "begin" 2 (=sharedConst) 22222 ;; 08
:: "while" 2 (=sharedConst) 33333 ;; 08
:: "do" 2 (=sharedConst) 44444 ;; 08
:: "of" 2 (=sharedConst) 55555 ;; 08
:: ":" 2 (=sharedConst) 66666 ;; 08
:: "{}" 2 (=sharedConst) 77777 ;; 08
(( Control structure high-level words ))
:: IF 7 (compile) (if) mark> controls ++ "if" exit ;; 80
:: ELSE 9 "if" ensureStruct
(compile) (branch) mark> swap resolve> "if" exit ;; 80
:: THEN 6 "if" ensureStruct controls -- resolve> exit ;; 80
:: BEGIN 5 mark< controls ++ "begin" exit ;; 80
:: AGAIN 8 "begin" ensureStruct controls --
(compile) (branch) resolve< exit ;; 80
:: UNTIL 8 "begin" ensureStruct controls --
(compile) (if) resolve< exit ;; 80
:: WHILE 7 "begin" ensureStruct
(compile) (if) mark> "while" exit ;; 80
:: REPEAT 10 "while" ensureStruct controls --
(compile) (branch) swap resolve< resolve> exit ;; 80
:: DO 9 (compile) (do) mark> mark< controls ++ zero "do" exit ;; 80
:: TIMES 4 (compile) one DO exit ;; 80
:: MSECS 9 (compile) (msecsDo) mark> mark< controls ++ one "do" exit ;; 80
:: LOOP 15 "do" ensureStruct controls --
(if) 5 (compile) (msecsLoop) (branch) 3 (compile) (loop)
resolve< resolve> exit ;; 80
:: +LOOP 10 "do" ensureStruct controls --
drop (compile) (+loop) resolve< resolve> exit ;; 80
:: CASE 6 (compile) dup zero controls ++ exit ;; 80
:: OF 7 (compile) (if) mark> (compile) drop "of" exit ;; 80
:: ENDOF 12 "of" ensureStruct
(compile) (branch) mark> swap resolve> (compile) dup swap 1+ exit ;; 80
:: ELSEOF 5 (lit) true override, OF exit ;; 80
:: ENDCASE 12 controls -- (lit) drop override,
one (do) 4 resolve> (loop) -2 exit ;; 80
(( Temporary variables (blocks) ))
:: (=template) 6 (compile) temp: r> @ , exit ;; 08
(( Build a compile-time temporary variable ))
:: TEMP 29 (parse) self <buildName>
"immediate" over name'flags toggle
default# <buildObject> dup rot name'object !
(lit) (=template) over object>store !
frameSize @ swap object>store cell+ !
frameSize ++ (compile) <temp> exit ;; 80
:: forgetTemp 17 dup name>object object>store @ (lit) (=template) =
(if) 7 dup name>object dup object>store <free> <free>
<deleteName> exit ;; 08
(( delete the compile-time temporary variable info ))
:: forgetTemps 13 name'succ @
?dup (if) 8 dup name'succ @ swap forgetTemp (branch) -9
exit ;; 08
:: { 9 (compile) ({) one frameSize !
controls ++ "{}" exit ;; 80
:: } 10 "{}" ensureStruct controls --
(compile) (}) latest @ forgetTemps exit ;; 80
(( File interface ))
(( Kevo supports very flexible I/O redirection. Each task can have basically an ))
(( unlimited number of nested input and output files. The number of nested input ))
(( files is limited by the size of return stack which does not grow automatically ))
(( (can be changed manually using 'resizeReturnStack', though).
(( raise 'eof' using the ugly way ))
:: raiseEof 8 true up @ (lit) 14 his ! exit ;; 08
:: fileShell 6 query interpret eof (if) -4 exit ;; 08
:: from 3 pushInfile fileShell exit ;; 0
:: endFrom 3 popInfile raiseEof exit ;; 0
:: to 3 "write" pushOutfile exit ;; 0
:: >>to 3 "append" pushOutfile exit ;; 0
:: endTo 2 popOutfile exit ;; 0
(( Block file auxiliaries ))
(( Note: in current implementation, block files are not task-specific ))
(( i.e., only one block file can be open at any time ))
:: b/buf 3 (lit) 1024 exit ;; 0
:: flush 3 save-buffers empty-buffers exit ;; 0
(( User tools and utilities ))
(( convert clock ticks to milliseconds and vice versa. ))
(( in Mac, clock ticks occur every 1/60 second. ))
:: ticks>msecs 7 (lit) 10 * (lit) 6 / exit ;; 0
:: msecs>ticks 7 (lit) 6 * (lit) 10 / exit ;; 0
(( delay for n milliseconds ))
:: msecs 6 (msecsDo) 4 yield (msecsLoop) -2 exit ;; 0
(( random number generator ))
:: seed 2 (=sharedVar) 0 ;; 08
:: randomize 7 clock (lit) 2147483647 * seed ! exit ;; 0
:: random 12 seed @ (lit) 16807 * (lit) 2147483647 umod dup seed ! exit ;; 0
:: rnd 8 over - 1+ random swap umod + exit ;; 0
(( execute host system commands. This does not work in Mac ))
:: $ 7 mustExecute zero (word) "literal, (compile) system exit ;; 80
:: isPrintable 6 (lit) 32 (lit) 127 between exit ;; 0
(( memory hex & ascii dump ))
:: dump 55 one (do) 51
dup h. ^^ : ^^ type
(lit) 15 (lit) 0 (do) 8
i over + b@ h.
(loop) -6 ^^ : ^^ type
(lit) 15 (lit) 0 (do) 18
i over + b@ dup
isPrintable (if) 4 emit (branch) 5 drop (lit) 95 emit
(loop) -16 cr
(lit) 16 +
(loop) -49
drop exit ;; 0
(( decompile a definition ))
:: SEE 4 ' (compile) see exit ;; 80
:: (-) 8 ^^ ( ^^ type . ^^ )^^ type exit ;; 08
:: mirror 35 ^^ Mirror of context: ^^ type .cs cr cr
self object>context context'first @
zero swap
?dup
(if) 19
dup name'name @ type
swap 1+ dup (-) swap cr
dup name>object see cr
name'succ @
(branch) -20 drop exit ;; 0
:: name. 6 name'name @ (lit) 19 rtype exit ;; 8
:: ?cr 12 swap 1+ dup (lit) 4 mod 0= (if) 2 cr swap exit ;; 08
(( name space contents listing ))
:: allnames 23 cr
object>context context'first @
zero swap
?dup
(if) 8
dup name. ?cr name'succ @
(branch) -9
cr . ^^ names.^^ type cr exit ;; 0
:: allwords 3 self allnames exit ;; 0
:: succWords 35 zero zero rot
?dup (if) 19
dup name'flags @ "hidden" and 0=
(if) 4 dup name. ?cr
rot 1+ -rot name'succ @
(branch) -20
cr . ^^ names (^^ type . ^^ in total).^^ type cr exit ;; 0
:: names 6 cr object>context context'first @ succWords exit ;; 0
:: words 3 self names exit ;; 0
(( :: mywords 7 ^^ boot^^ find name'succ @ succWords exit ;; 0 ))
:: prevWords 19 zero swap
?dup
(if) 8
dup name. ?cr name'prev @
(branch) -9
cr . ^^ names.^^ type cr exit ;; 0
(( list the words in the predecessor link order ))
(( each thread separately ))
:: .threads 14 #threads 1- zero
(do) 9
i self object>context context'thread @ prevWords
(loop) -7 exit ;; 0
(( System startup ))
:: hello 11 cr ^^ -- Kevo Kernel v0.9b6 --^^ type cr
^^ -- (c) A. Taivalsaari 1993 --^^ type cr cr exit ;; 0
:: demoInfo 5 ^^ Type 'demo' to load the demo programs.^^ type cr exit ;; 0
:: demo 4 ^^ demo.kevo^^ from exit ;; 0
:: SystemInit 15 randomize (( initialize random number seed ))
(lit) 50 basePriority ! (( base priority of new tasks ))
(lit) 1 eventSlice ! (( how much time Mac receives ))
(lit) 4 eventDelay ! (( how often event loop will be called ))
demoInfo boot ;; 0
:: boot 5 Root >self hello reboot shell ;; 0